﻿using System;
using System.Collections.Generic;
using System.Text;
using eslib.nnp5.layers;

namespace eslib.nnp5
{
    /// <summary>
    /// ACK包
    /// </summary>
    public class ACKPkg : TransportPKGBase
    {
        #region 构造ACK

        private ACKPkg()
        {
        }

        /// <summary>
        /// 获取ACK数据包
        /// </summary>
        /// <returns></returns>
        public override byte[] makePKG()
        {
            List<byte> pkgOri = new List<byte>();
            
            pkgOri.AddRange(ackSign);      //添加ack标识
            pkgOri.AddRange(BitConverter.GetBytes(pkgID));     //包ID
            pkgOri.AddRange(prm);      //添加ack参数
            

            //整体FF转义
            List<byte> pkg = ffTransData(pkgOri);

            //补充包头包尾
            pkg.InsertRange(0, head);
            pkg.AddRange(tail);

            return pkg.ToArray();
        }



        /// <summary>
        /// 还原ACK数据包
        /// </summary>
        /// <param name="pkg">包缓存(不带头尾)</param>
        /// <returns></returns>
        public static ACKPkg RestoreACK(byte[] pkg)
        {
            if (pkg.Length != 12) throw new TransportLayerException("ACK包的数据长度不等于12");

            ACKPkg ack = new ACKPkg();

            //包ID
            ack.pkgID = BitConverter.ToUInt32(pkg, 4);

            //ack参数
            for (int i = 0; i < 4; i++)
            {
                ack.prm[i] = pkg[i + 8];
            }
            return ack;
        }


        /// <summary>
        /// 创建成功型ACK包
        /// </summary>
        /// <param name="pkgID">对应的包ID</param>
        /// <returns></returns>
        public static ACKPkg CreateSuccessACK(uint pkgID)
        {
            ACKPkg ack = new ACKPkg();
            ack.setPkgID(pkgID);
            return ack;
        }


        /// <summary>
        /// 创建失败型ACK包
        /// </summary>
        /// <param name="pkgID">对应的包ID</param>
        /// <param name="param">错误类型</param>
        /// <returns></returns>
        public static ACKPkg CreateFailACK(uint pkgID, uint param)
        {
            ACKPkg pkg = new ACKPkg();
            pkg.setPkgID(pkgID);
            pkg.setParam(param);
            return pkg;
        }

        #endregion





        //////数据结构//////

        #region ack标识

        /// <summary>
        /// ack标识
        /// </summary>
        internal static byte[] ackSign = new byte[4] { 0, 0, 0, 0 };

        #endregion





        #region ACK参数

        /// <summary>
        /// ACK参数
        /// </summary>
        private byte[] prm = new byte[4] { 0, 0, 0, 0 };

        /// <summary>
        /// 获取ack参数
        /// </summary>
        /// <returns></returns>
        public uint getParam()
        {
            return BitConverter.ToUInt32(prm, 0);
        }

        /// <summary>
        /// 设置ack参数
        /// </summary>
        /// <param name="param"></param>
        private void setParam(uint param)
        {
            this.prm = BitConverter.GetBytes(param);
        }

        #endregion

    }
}
